package cn.how2go.net.server.handler;

import cn.how2go.net.server.base.SessionData;
import cn.how2go.net.server.bean.ChannelStatus;
import cn.how2go.net.server.protocol.JTBytes;
import cn.how2go.net.server.vo.CtxMessage;
import cn.how2go.net.server.util.BinaryUtil;
import cn.how2go.net.server.util.DateUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2019/3/4.
 */
public class NetServerHandler extends SimpleChannelInboundHandler<Object> {
    public Logger logger = LoggerFactory.getLogger(NetServerHandler.class);
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        //解析报文开始
        ByteBuf buf = (ByteBuf)msg;
        byte[] message = new byte[buf.readableBytes()];
        buf.readBytes(message);
        //获取校验码 和 报文中校验 比较
        byte crc = BinaryUtil.GetCheckXor(message,1,message.length-2);
        System.out.println("JT808<<<<<<>>>>>>>"+BinaryUtil.ToHexFormatString(message));
        ChannelStatus cs = SessionData.ALLLINK.get(ctx);
        if (0x7e != BinaryUtil.getMsgHead(message[0]) || 0x7e != BinaryUtil.getMsgHead(message[message.length-1]) || crc != message[message.length-2]) {
            //错误报文记录到缓存中
            cs.setBadmsg(cs.getBadmsg()+1);
            if(cs.getBadmsg()>SessionData.BREAKMAXMESSAGE){
                cs.setBad(true);
            }
        }else {
            JTBytes jtBytes = new JTBytes();
            jtBytes.read(message);
            //组合终端串号，便于缓存同步终端串号
            String simno = jtBytes.getHeader().getSimno();
            //更新通道缓存
            cs.setSimno(simno);
            cs.setLastSend(new Date());
            cs.setBadmsg(0);
            //更新状态重新写入缓存
            SessionData.ALLLINK.put(ctx, cs);
            SessionData.AllTERMINAL.put(simno,ctx);
            //放到消息队列中
            Map<String, String> map = new HashMap<>();
            map.put("message", "[" + simno + "][" +
                    DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") +
                    "]" + BinaryUtil.ToHexFormatString(message));
            SessionData.MESSAGELIST.add(map);
            //创建消息报文，并放到内存队列中
            CtxMessage ctxMessage = new CtxMessage(ctx, jtBytes);
            //CtxMessageService.write(ctxMessage);
            SessionData.RECEIVE_MESSAGE.offer(ctxMessage);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        SessionData.ALLLINK.put(ctx,new ChannelStatus(ctx,false,new Date()));
        super.channelRegistered(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
    }
}
